<template>
  <view class="container">
    <!-- 内容区域 -->
    <view class="content-area">
      <!-- 状态标识 -->
      <view class="status-indicator">
        <text class="status-value" :style="{ color: status === 'OK' ? 'green' : 'red' }">{{ status }}</text>
        <view class="progress-info">
          <text class="progress-text">{{ scannedCount }}/{{ totalTasks }}</text>
        </view>
      </view>

      <!-- 信息显示组 -->
      <view class="info-group">
        <view class="info-item-inline">
          <text class="label-inline">订单No:</text>
          <text class="value-inline">{{ orderNo }}</text>
        </view>

        <view class="info-item-inline">
          <text class="label-inline">实装机ID:</text>
          <text class="value-inline">{{ mountingMachineId }}</text>
        </view>
        
        <view class="info-item-inline">
          <text class="label-inline">实装面:</text>
          <text class="value-inline">{{ mountingSurface }}</text>
        </view>

        <view class="info-item-inline">
          <text class="label-inline">部品批次ID:</text>
          <view class="input-container">
            <input 
              class="input-field bold-border bold-text small-input" 
              type="text" 
              v-model="inputPartBatchId"
              @input="onPartInput"
              @confirm="onPartScan"
              placeholder="请扫描部品批次ID" 
              :focus="isPartBatchIdFocused"
              confirm-type="done"
              :cursor-spacing="0"
              :adjust-position="false"
              hold-keyboard="false"
              inputmode="none"
            />
            <view v-if="inputPartBatchId && inputPartBatchId.trim().length > 0" class="clear-btn" @click="onPartBatchIdClear">
              <text class="clear-icon">×</text>
            </view>
          </view>
        </view>

        <view class="info-item-inline">
          <text class="label-inline">Z轴ID:</text>
          <text class="value-inline">{{ zAxisId }}</text>
        </view>

        <view class="info-item-inline">
          <text class="label-inline">部品品番:</text>
          <text class="value-inline">{{ partNumber }}</text>
        </view>
      </view>
    </view>

    <!-- 底部按钮区域 -->
    <div class="button-group">
        <button class="btn btn-back" @click="goBack" :disabled="isProcessing" :class="{ 'btn-disabled': isProcessing }">返回</button>
        <button class="btn btn-continue" @click="continueTask" :disabled="status !== 'OK'" :class="{ 'btn-disabled': status !== 'OK' }">继续</button>
        <button class="btn btn-complete" @click="handleCompleteClick" :disabled="!canSubmit" :class="{ 'btn-disabled': !canSubmit }">完成</button>
    </div>
    
    <!-- 自定义认证模态框 -->
    <view class="auth-modal" v-if="showAuthModal">
      <view class="auth-modal-content">
        <view class="auth-modal-header">
          <text class="auth-modal-title">管理员验证</text>
        </view>
        <view class="auth-modal-body">
          <!-- 警告信息 -->
          <view class="auth-warning">
            <text class="auth-warning-text">警告：执行此操作将清除<br/>目前为止的登录信息！</text>
          </view>
          <!-- 使用 UniApp 的 input 组件 -->
          <view class="auth-input-container">
            <input 
              class="auth-input" 
              v-model="authUsername" 
              placeholder="用户名" 
              :focus="isUsernameInputFocused" 
              :cursor-spacing="0" 
              :adjust-position="false" 
              hold-keyboard="false" 
              inputmode="none" 
            />
            <view v-if="authUsername && authUsername.trim().length > 0" class="auth-clear-btn" @click="clearAuthUsername">
              <text class="clear-icon">×</text>
            </view>
          </view>
          <view class="auth-input-container">
            <input 
              class="auth-input" 
              v-model="authPassword" 
              placeholder="密码" 
              password="true" 
              @confirm="handleAuthSubmit" 
              :cursor-spacing="0" 
              :adjust-position="false" 
              hold-keyboard="false" 
              inputmode="none" 
            />
            <view v-if="authPassword && authPassword.trim().length > 0" class="auth-clear-btn" @click="clearAuthPassword">
              <text class="clear-icon">×</text>
            </view>
          </view>
        </view>
        <view class="auth-modal-footer">
          <button class="auth-button auth-button-cancel" @click="closeAuthModal">取消</button>
          <button class="auth-button auth-button-confirm" @click="handleAuthSubmit">确认</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { logRollOperation } from '@/api/roll';
import { saveScanRecords } from '@/api/roll';
import { validateUser } from '@/api/auth';
import { ScanHandler } from '@/utils/scanHandler';
import { 
  getBaseCacheData,
  getScanCacheData, 
  addSuccessScanRecord,
  addFailureScanRecord,
  getUniquePartCount as getCacheUniquePartCount,
  checkDuplicateLot as checkCacheDuplicateLot,
  clearScanCacheData,
  clearAllCacheData,
  prepareSubmissionData
} from '@/utils/cacheManager';

export default {
  data() {
    return {
      // From URL
      operatorId: '',
      operatorName: '',

      // From Cache (本地缓存①)
      baseCache: null,     // 基础订单数据
      scanCache: null,     // 扫描记录数据
      
      // Displayed values
      orderNo: '',
      mountingMachineId: '',
      mountingSurface: '',
      partNumber: '',
      zAxisId: '',
      
      // Data for input
      inputPartBatchId: '',
      
      // Page State
      status: '', // OK, NG, or empty
      lastFailureReason: '', // 用于NG状态的错误原因
      isProcessing: false, // 防止重复点击
      
      // 响应式数据（确保界面更新）
      currentUniquePartCount: 0, // 当前唯一部品数量
      forceUpdateFlag: 0, // 强制更新标志
      
      cacheKey: '',
      showAuthModal: false,
      authUsername: '',
      authPassword: '',
      isUsernameInputFocused: false,
      isPartBatchIdFocused: false, // 初始化为false，通过方法触发焦点状态变化
      
      // 失败计数器（防止缓存堆积）
      authFailCount: 0,
      submitFailCount: 0,
      AUTH_FAIL_LIMIT: 3,
      SUBMIT_FAIL_LIMIT: 5,
      
      // 错误类型定义
      SMT_CONTENT_TYPES: {
        FORMAT_ERROR_NO_A0P: 'FORMAT_ERROR:缺少A0P分隔符',
        FORMAT_ERROR_EMPTY: 'FORMAT_ERROR:扫描值为空',
        LOT_ALREADY_SCANNED: 'LOT_ERROR:该部品相同批次已扫描',
        LOT_EMPTY: 'LOT_ERROR:批次号为空',
        LOT_TOO_LONG: 'LOT_ERROR:批次号过长',
        PART_NOT_FOUND: 'PART_ERROR:部品号不存在',
        DATA_ERROR_MISSING_BOM: 'DATA_ERROR:BOM数据缺失',
        DATA_ERROR_MISSING_ROLLNO: 'DATA_ERROR:Roll号缺失',
        SYSTEM_ERROR_BOM_MISSING: 'SYSTEM_ERROR:BOM项缺失',
        SYSTEM_ERROR_LOT_MISSING: 'SYSTEM_ERROR:批次号缺失',
        SYSTEM_ERROR_SAVE_FAILED: 'SYSTEM_ERROR:保存失败',
        USER_CONFIRMED_FAILURE: 'USER_ERROR:用户确认失败状态',
        SYSTEM_ERROR_CACHE: 'SYSTEM_ERROR:缓存读取失败'
      },
      
      // 扫码处理器
      scanHandler: null
    };
  },
  computed: {
    totalTasks() {
      return this.baseCache && this.baseCache.partList ? this.baseCache.partList.length : 0;
    },
    // 基于唯一部品数量计算进度（使用新缓存系统）
    scannedCount() {
      // 使用forceUpdateFlag确保计算属性重新计算
      this.forceUpdateFlag; // 访问响应式数据以触发更新
      const count = getCacheUniquePartCount();
      // 同步更新响应式数据
      if (this.currentUniquePartCount !== count) {
        this.currentUniquePartCount = count;
      }
      return count;
    },
    // 检查是否可以提交（所有部品都必须至少扫描一次）
    canSubmit() {
      // 使用forceUpdateFlag确保计算属性重新计算
      this.forceUpdateFlag; // 访问响应式数据以触发更新
      
      const uniquePartCount = getCacheUniquePartCount();
      const totalParts = this.totalTasks;
      
      // 严格检查：必须存在有效的基础缓存数据，且唯一部品数量必须等于总部品数量
      if (!this.baseCache || !this.baseCache.partList || this.baseCache.partList.length === 0) {
        return false;
      }
      
      if (totalParts === 0) {
        return false;
      }
      
      // 严格要求：唯一部品数量必须等于总部品数量
      const canSubmitResult = uniquePartCount === totalParts;
      
      console.log('🔍 canSubmit 计算:', {
        uniquePartCount,
        totalParts,
        canSubmitResult,
        forceUpdateFlag: this.forceUpdateFlag
      });
      
      return canSubmitResult;
    }
  },
  mounted() {
    // 直接初始化扫码处理器（模仿程序选择页面的成功模式）
    this.initializeScanHandler();
  },
  beforeDestroy() {
    // 清理扫码处理器
    if (this.scanHandler) {
      this.scanHandler.destroy();
    }
  },
  onLoad(options) {
    
    // #ifdef APP-PLUS
    // PDA返回键处理将在onBackPress方法中实现
    // #endif
    
    // 1. Get operator info from URL (if passed directly)
    this.operatorId = options.operatorId || '';
    this.operatorName = options.operatorName || '';

    // 2. 使用双缓存系统加载数据
    try {
      // 2.1 加载本地缓存① - 基础订单数据
      this.baseCache = getBaseCacheData();
      if (!this.baseCache) {
        console.error('❌ 本地缓存① 基础订单数据不存在');
        this.handleError('缺少基础订单数据，请从作业员确认页面重新开始操作');
        return;
      }
      
      // 2.2 加载本地缓存② - 扫描记录数据
      this.scanCache = getScanCacheData();
      
      // 2.3 检查基础缓存是否有smtSide字段，如果没有可能是旧缓存，需要重新设置
      if (!this.baseCache.smtSide) {
        console.warn('⚠️ 基础缓存缺少smtSide字段，可能需要重新开始流程');
        uni.showToast({
          title: '缓存数据异常，请重新扫描程序',
          icon: 'none',
          duration: 2000
        });
        setTimeout(() => {
          uni.redirectTo({
            url: '/pages/select/select'
          });
        }, 2000);
        return;
      }
      
      // 2.4 确保扫描缓存的smtSide字段被正确设置
      if (!this.scanCache.baseInfo.smtSide && this.baseCache.smtSide) {
        this.scanCache.baseInfo.smtSide = this.baseCache.smtSide;
        // 更新本地缓存
        this.updateScanCacheData();
      }
      
      // 2.5 映射基础数据到页面显示字段
      this.orderNo = this.baseCache.orderNo || '';
      this.mountingMachineId = this.baseCache.mounterId || '';
      this.mountingSurface = this.scanCache.baseInfo.smtSide || this.baseCache.smtSide || '1'; // 优先从扫描缓存获取，其次从基础缓存获取
      
      // 2.6 使用缓存数据中的操作员信息
      if (this.baseCache.operatorId) {
        this.operatorId = this.baseCache.operatorId;
      }
      
      // 2.7 初始化响应式数据
      this.initializeReactiveData();
      
      console.log('✅ 双缓存系统数据加载完成:', {
        orderNo: this.orderNo,
        mounterId: this.mountingMachineId,
        partListCount: this.baseCache.partList?.length || 0,
        successRecords: this.scanCache.successRecords?.length || 0
      });
      
    } catch (error) {
      console.error('❌ 双缓存系统数据加载失败:', error);
      this.handleError('加载数据失败，请重新开始操作');
      return;
    }
    
    // 数据加载完成后，确保焦点设置正确（重要：这个时机很关键）
    this.$nextTick(() => {
      // 增加一些延迟确保DOM完全渲染后设置焦点
      setTimeout(() => {
        this.focusPartBatchIdInput();
        // 执行系统预热，解决首次扫描问题
        setTimeout(() => {
          this.performSystemWarmup();
        }, 200);
      }, 100);
    });
  },
  
  // #ifdef APP-PLUS
  onBackPress(options) {
    // 弹出认证模态框而不是直接返回
    this.showAuthModal = true;
    this.isUsernameInputFocused = true;
    return true; // 阻止默认返回行为
  },
  // #endif
  
  onUnload() {
    // 页面卸载时清理未提交的缓存（防止缓存堆积）
    console.log('⚠️ 页面即将卸载，检查是否需要清理缓存');
    
    // 如果有失败累积或者用户没有完成任务就退出，清理所有缓存
    if (this.submitFailCount > 0 || this.authFailCount > 0) {
      console.log('📤 页面卸载，清理失败累积的缓存');
      this.clearAllCache();
    }
  },
  
  methods: {
    // 初始化扫码处理器
    initializeScanHandler() {
      this.scanHandler = new ScanHandler({
        minScanLength: 6, // 部品批次ID最小长度检查
        onScanComplete: (scanValue) => {
          this.handlePartBatchScan(scanValue);
        },
        onScanError: (error, scanValue) => {
          uni.showToast({
            title: '扫码处理失败',
            icon: 'none',
            duration: 2000
          });
        }
      });
    },
    
    // 部品批次ID输入处理 - 实时更新扫码缓冲区
    onPartInput(e) {
      if (this.scanHandler) {
        this.scanHandler.handleInput(e.target.value.trim());
      }
    },
    
    // 部品批次ID确认处理（回车键按下时）- PDA的最后一个回车触发分割
    onPartScan() {
      if (this.scanHandler && this.inputPartBatchId.trim()) {
        // 确保handleInput先被调用（解决第一次扫描@input事件可能未触发的问题）
        this.scanHandler.handleInput(this.inputPartBatchId.trim());
        // 然后调用handleConfirm触发分割
        this.scanHandler.handleConfirm(this.inputPartBatchId.trim());
      }
    },
    
    // 处理部品批次扫描数据
    handlePartBatchScan(scanValue) {
      if (this.isProcessingScan) {
        return;
      }
      
      this.isProcessingScan = true;
      
      
      // Keep input value for display
      this.inputPartBatchId = scanValue;
      
      // Set focus back to the hidden input for the next scan
      this.$nextTick(() => {
        // Reset focus state to ensure the input is ready for the next scan
        this.isPartBatchIdFocused = false;
        setTimeout(() => {
          this.isPartBatchIdFocused = true;
        }, 100);
      });

      if (!scanValue) {
        this.handleScanFailure('', 'FORMAT_ERROR_EMPTY');
        return;
      }

      if (!scanValue.includes('A0P')) {
        this.handleScanFailure(scanValue, 'FORMAT_ERROR_NO_A0P');
        return;
      }

      const parts = scanValue.split('A0P');
      const partIdBase = parts[0]; // 部品ID基础部分
      const lotNo = parts[1]; // 批次号
      
      if (!lotNo) {
        this.handleScanFailure(scanValue, 'LOT_EMPTY', partIdBase);
        return;
      }
      
      if (lotNo.length > 40) {
        this.handleScanFailure(scanValue, 'LOT_TOO_LONG', lotNo);
        return;
      }

      // 在基础缓存中查找对应的部品
      if (!this.baseCache || !this.baseCache.partList) {
        this.handleScanFailure(scanValue, 'DATA_ERROR_MISSING_BOM');
        return;
      }
      
      const bomItem = this.baseCache.partList.find(item => {
        const bomPartIdBase = item.partId.split('-')[0];
        return bomPartIdBase === partIdBase;
      });

      if (!bomItem) {
        this.handleScanFailure(scanValue, 'PART_NOT_FOUND');
        return;
      }
      
      // 检查是否为重复的部品+批次组合（使用新缓存系统）
      if (checkCacheDuplicateLot(bomItem.partId, lotNo)) {
        this.handleScanFailure(scanValue, 'LOT_ALREADY_SCANNED', `${bomItem.partId},${lotNo}`);
        return;
      }
      
      // 扫描成功
      this.handleScanSuccess(bomItem, lotNo, scanValue);
    },
    // 扫描成功处理
    handleScanSuccess(bomItem, lotNo, scanValue) {
      this.status = 'OK';
      this.partNumber = bomItem.partId;
      this.zAxisId = bomItem.rollNo;
      
      // 仅显示A0P后面的批次号
      this.inputPartBatchId = lotNo;
      
      // 检查是否为新部品（用于进度计算）
      const scanCacheData = getScanCacheData();
      const existingPartRecords = scanCacheData.successRecords.filter(record => 
        record.partId === bomItem.partId
      );
      
      if (existingPartRecords.length === 0) {
        // 情况1：部品号在本地扫描成功缓存中不存在
        uni.showToast({ title: '部品扫描成功', icon: 'success' });
      } else {
        // 情况2：部品号存在，但批次号不存在
        uni.showToast({ title: '部品批次扫描成功', icon: 'success' });
      }
      
      // 重置处理状态
      this.isProcessingScan = false;
    },
    
    // 扫描失败处理
    handleScanFailure(scannedValue, errorType, additionalInfo = '') {
      this.status = 'NG';
      this.lastFailureReason = this.getErrorMessage(errorType);
      this.partNumber = '';
      this.zAxisId = '';
      
      // 使用新缓存系统保存失败记录
      const smtContent = this.generateSmtContent(errorType, scannedValue, additionalInfo);
      const failureRecord = {
        smtContent: smtContent
      };
      
      // 只有在能解析出部品ID时才添加partId字段
      if (scannedValue && scannedValue.includes('A0P')) {
        const partIdBase = scannedValue.split('A0P')[0];
        if (partIdBase && partIdBase.trim()) {
          failureRecord.partId = partIdBase.length > 10 ? partIdBase.substring(0, 10) : partIdBase;
        }
      }
      
      addFailureScanRecord(failureRecord);
      
      // 显示错误提示
      uni.showToast({
        title: this.lastFailureReason,
        icon: 'none',
        duration: 2000
      });
      
      // 重置处理状态
      this.isProcessingScan = false;
    },
    
    // 获取错误消息
    getErrorMessage(errorType) {
      const messages = {
        'FORMAT_ERROR_NO_A0P': '扫描格式不正确，缺少A0P分隔符',
        'FORMAT_ERROR_EMPTY': '扫描值为空',
        'LOT_EMPTY': '批次号为空',
        'LOT_TOO_LONG': '批次号过长 (最大40字符)',
        'PART_NOT_FOUND': '错误部品号不存在！请重新扫描！',
        'LOT_ALREADY_SCANNED': '该部品相同批次已扫描',
        'DATA_ERROR_MISSING_BOM': 'BOM数据缺失',
        'DATA_ERROR_MISSING_ROLLNO': 'Roll号缺失'
      };
      return messages[errorType] || '未知错误';
    },
    // ========== 双缓存系统管理方法 ==========
    
    // 生成smtContent
    generateSmtContent(errorType, scannedValue, additionalInfo = '') {
      const baseMessages = {
        'FORMAT_ERROR_NO_A0P': `FORMAT_ERROR:缺少A0P分隔符[扫描值:${scannedValue}]`,
        'FORMAT_ERROR_EMPTY': `FORMAT_ERROR:扫描值为空`,
        'PART_NOT_FOUND': `PART_ERROR:部品号不存在[扫描值:${scannedValue}]`,
        'LOT_ALREADY_SCANNED': `LOT_ERROR:该部品相同批次已扫描[${additionalInfo}]`,
        'LOT_EMPTY': `LOT_ERROR:批次号为空[部品:${additionalInfo}]`,
        'LOT_TOO_LONG': `LOT_ERROR:批次号过长[批次:${additionalInfo}]`,
        'DATA_ERROR_MISSING_BOM': `DATA_ERROR:BOM数据缺失`,
        'DATA_ERROR_MISSING_ROLLNO': `DATA_ERROR:Roll号缺失[部品:${additionalInfo}]`,
        'SYSTEM_ERROR_CACHE': `SYSTEM_ERROR:缓存读取失败`,
        'SYSTEM_ERROR_BOM_MISSING': `SYSTEM_ERROR:BOM项缺失[部品:${additionalInfo}]`,
        'SYSTEM_ERROR_LOT_MISSING': `SYSTEM_ERROR:批次号缺失[部品:${additionalInfo}]`,
        'SYSTEM_ERROR_SAVE_FAILED': `SYSTEM_ERROR:保存失败[${additionalInfo}]`,
        'USER_CONFIRMED_FAILURE': `USER_ERROR:用户确认失败状态[${additionalInfo}]`
      };
      
      return baseMessages[errorType] || `UNKNOWN_ERROR:${scannedValue}`;
    },
    
    // ========== 辅助方法 ==========
    
    
    // 更新扫描缓存数据
    updateScanCacheData() {
      try {
        const success = setScanCacheData(this.scanCache);
        if (success) {
          console.log('✅ 扫描缓存数据已更新');
        } else {
          console.error('❌ 更新扫描缓存数据失败');
        }
      } catch (error) {
        console.error('❌ 更新扫描缓存数据异常:', error);
      }
    },
    
    // 原生清除按钮事件处理（美化的清除按钮）
    onPartBatchIdClear() {
      // 清除输入值和相关状态
      this.inputPartBatchId = '';
      this.status = '';
      this.partNumber = '';
      this.zAxisId = '';
      
      // 重新设置焦点到输入框
      this.$nextTick(() => {
        this.focusPartBatchIdInput();
      });
    },
    
    // 认证模态框清除按钮事件处理
    clearAuthUsername() {
      this.authUsername = '';
    },
    
    clearAuthPassword() {
      this.authPassword = '';
    },
    
    // 处理错误的方法
    handleError(message) {
      uni.showToast({
        title: message,
        icon: 'none',
        duration: 3000
      });
    },
    
    
    // 强制界面更新
    forceUIUpdate() {
      // 更新强制更新标志以触发计算属性重新计算
      this.forceUpdateFlag++;
      
      // 使用nextTick确保在下个渲染循环中更新
      this.$nextTick(() => {
        const newCount = getCacheUniquePartCount();
        this.currentUniquePartCount = newCount;
        
        // 双重确保：强制触发Vue的响应式系统
        this.$forceUpdate();
      });
    },
    
    // 初始化响应式数据
    initializeReactiveData() {
      const currentCount = getCacheUniquePartCount();
      this.currentUniquePartCount = currentCount;
      this.forceUpdateFlag = Date.now();
      
      // 强制触发一次更新
      this.$forceUpdate();
    },
    
    // 从显示的批次ID中提取批次号
    getLotNoFromDisplay() {
      if (!this.inputPartBatchId || !this.inputPartBatchId.includes('A0P')) {
        return null;
      }
      const parts = this.inputPartBatchId.split('A0P');
      return parts[1] || null;
    },
    
    // 获取最后一次失败的原因（用于NG状态显示）
    getLastFailureReason() {
      return this.lastFailureReason || '扫描失败，请检查后重试';
    },
    
    // 检查当前是否已有失败记录（防止重复保存）
    hasCurrentFailureRecord() {
      // 简化实现，实际可以通过时间戳或其他标识来判断
      return false;
    },
    
    
    // 重置扫描界面
    resetScanInterface() {
      this.status = '';
      this.partNumber = '';
      this.zAxisId = '';
      this.inputPartBatchId = '';
      
      // 将焦点设置回输入框
      this.$nextTick(() => {
        // 重置焦点状态以确保输入框可以接收下一次扫描
        this.isPartBatchIdFocused = false;
        setTimeout(() => {
          this.isPartBatchIdFocused = true;
        }, 100);
      });
    },
    
    // ========== 按钮操作方法 ==========
    
    // 修改：处理返回按钮点击事件
    goBack() {
      // 如果正在处理，阻止返回操作
      if (this.isProcessing) {
        uni.showToast({
          title: '正在处理中，请稍等',
          icon: 'none',
          duration: 1500
        });
        return;
      }
      
      // 直接显示自定义认证模态框
      this.showAuthModal = true;
      // 设置用户名输入框聚焦状态为 true
      this.isUsernameInputFocused = true;
    },

    // 新增：处理认证提交
    async handleAuthSubmit() {
      const username = this.authUsername.trim();
      const password = this.authPassword.trim();

      // 显示加载状态
      uni.showLoading({ 
        title: '验证中...',
        mask: true 
      });

      try {
        // 调用后端API进行用户认证
        const response = await validateUser(username, password);
        
        
        // 检查响应状态和数据
        if (response && response.statusCode === 200 && response.data && response.data.code === '00000') {
          // 验证成功
          // 在清空缓存和跳转前，先取消聚焦状态
          this.isUsernameInputFocused = false;
          uni.hideLoading();
          this.clearCacheAndNavigate();
        } else {
          // 验证失败
          uni.hideLoading();
          const errorMessage = (response && response.data && response.data.message) || '用户名或密码错误';
          uni.showToast({
            title: errorMessage,
            icon: 'none'
          });
        }
      } catch (error) {
        uni.hideLoading();
        // 显示用户友好的错误信息
        const userMessage = error.userMessage || 
                           error.message || 
                           '认证失败，请重试';
        uni.showToast({
          title: userMessage,
          icon: 'none'
        });
        // 验证失败后，可以考虑保持聚焦在用户名输入框，方便用户重新输入
        // 认证失败多次后清理缓存（防止缓存堆积）
        this.incrementAuthFailCount();
      }
    },

    // 清空缓存并跳转（使用双缓存系统）
    clearCacheAndNavigate() {
      try {
        console.log('🧹 开始清除双缓存数据...');
        
        // 清除双缓存系统数据
        const clearResult = clearAllCacheData();
        console.log('双缓存清理结果:', clearResult);
        
        // 显示清理完成的提示
        uni.showToast({
          title: '缓存已清理',
          icon: 'success',
          duration: 1000
        });

        // 关闭认证模态框
        this.showAuthModal = false;
        this.authUsername = '';
        this.authPassword = '';

        // #ifdef APP-PLUS
        // 移除返回键监听
        const currentPage = getCurrentPages()[getCurrentPages().length - 1];
        if (currentPage && currentPage.onBackPress) {
          currentPage.onBackPress = null;
        }
        // #endif

        // 跳转到程序选择页面
        uni.redirectTo({
          url: '/pages/select/select'
        });
      } catch (error) {
        uni.showToast({
          title: '操作失败，请重试',
          icon: 'none'
        });
      }
    },

    // 新增：关闭认证模态框
    closeAuthModal() {
      this.showAuthModal = false;
      this.authUsername = '';
      this.authPassword = '';
      // 关闭模态框时，取消聚焦状态
      this.isUsernameInputFocused = false;
    },
    continueTask() {
      // 1. 防止重复点击
      if (this.isProcessing) {
        return;
      }
      this.isProcessing = true;
      
      try {
        // 2. 根据当前状态执行不同逻辑
        if (this.status === 'OK') {
          this.handleSuccessFlow();
        } else if (this.status === 'NG') {
          this.handleFailureFlow();
        } else {
          // 状态为空，提示用户先进行扫描
          uni.showToast({ 
            title: '请先扫描部品批次ID', 
            icon: 'none' 
          });
          return;
        }
        
      } catch (error) {
        uni.showToast({ title: '操作失败，请重试', icon: 'none' });
      } finally {
        this.isProcessing = false;
      }
    },
    
    // 处理成功状态的流程
    handleSuccessFlow() {
      // 1. 查找对应的BOM项
      const bomItem = this.baseCache.partList.find(item => 
        item.partId === this.partNumber
      );
      
      if (!bomItem) {
        uni.showToast({ 
          title: '无法找到对应的BOM项', 
          icon: 'none' 
        });
        // 保存为系统错误到失败记录
        const smtContent = this.generateSmtContent('SYSTEM_ERROR_BOM_MISSING', this.inputPartBatchId, this.partNumber);
        addFailureScanRecord({ smtContent: smtContent });
        this.resetScanInterface();
        return;
      }
      
      // 2. 获取批次号
      // 直接使用inputPartBatchId作为批次号，因为它已经是纯批次号（不含A0P）
      const lotNo = this.inputPartBatchId;
      if (!lotNo) {
        uni.showToast({ 
          title: '无法获取批次号', 
          icon: 'none' 
        });
        // 保存为系统错误到失败记录
        const smtContent = this.generateSmtContent('SYSTEM_ERROR_LOT_MISSING', this.inputPartBatchId, this.partNumber);
        addFailureScanRecord({ smtContent: smtContent });
        this.resetScanInterface();
        return;
      }
      
      // 3. 使用新缓存系统保存成功记录
      const scanRecord = {
        partId: bomItem.partId,
        lotNo: lotNo,
        rollNo: bomItem.rollNo,
        rollMngNo: this.baseCache.rollMngNo || '',
        smtSide: this.mountingSurface || '1'
      };
      
      const success = addSuccessScanRecord(scanRecord);
      if (!success) {
        uni.showToast({ 
          title: '保存记录失败，请重试', 
          icon: 'none' 
        });
        // 保存为系统错误到失败记录
        const smtContent = this.generateSmtContent('SYSTEM_ERROR_SAVE_FAILED', this.inputPartBatchId, this.partNumber + ',' + lotNo);
        addFailureScanRecord({ smtContent: smtContent });
        this.resetScanInterface();
        return;
      }
      
      // 4. 成功反馈
      uni.showToast({ 
        title: '记录保存成功', 
        icon: 'success' 
      });
      
      // 5. 强制界面更新
      this.forceUIUpdate();
      
      // 6. 界面重置
      this.resetScanInterface();
    },
    
    // 处理失败状态的流程
    handleFailureFlow() {
      // 1. 显示当前的错误信息（从之前的扫描失败中获取）
      const lastFailureReason = this.getLastFailureReason();
      uni.showToast({ 
        title: lastFailureReason || '扫描失败', 
        icon: 'none' 
      });
      
      // 2. 如果还没有失败记录，则保存当前的失败状态
      if (!this.hasCurrentFailureRecord()) {
        const smtContent = this.generateSmtContent('USER_CONFIRMED_FAILURE', this.inputPartBatchId, '用户确认失败状态');
        addFailureScanRecord({ smtContent: smtContent });
      }
      
      // 3. 界面重置
      this.resetScanInterface();
    },
    
    // 完成按钮点击处理（增加双重检查）
    handleCompleteClick() {
      console.log('🔘 完成按钮被点击:', {
        canSubmit: this.canSubmit,
        uniquePartCount: getCacheUniquePartCount(),
        totalTasks: this.totalTasks,
        isProcessing: this.isProcessing
      });
      
      // 双重检查：如果不能提交，直接阻止
      if (!this.canSubmit) {
        console.log('🚫 按钮被阻止点击 - canSubmit为false');
        uni.showToast({ 
          title: '请完成所有部品扫描后再提交', 
          icon: 'none' 
        });
        return;
      }
      
      // 如果可以提交，调用实际的提交方法
      this.completeTask();
    },
    
    completeTask() {
      // 1. 检查是否有数据可以提交
      if (!this.canSubmit) {
        console.log('🚫 完成按钮被点击但canSubmit为false:', {
          canSubmit: this.canSubmit,
          uniquePartCount: getCacheUniquePartCount(),
          totalTasks: this.totalTasks,
          forceUpdateFlag: this.forceUpdateFlag
        });
        uni.showToast({ 
          title: '没有可提交的记录，请先进行扫描', 
          icon: 'none' 
        });
        return;
      }
      
      // 2. 防止重复点击
      if (this.isProcessing) {
        return;
      }
      this.isProcessing = true;
      
      // 3. 显示加载状态
      uni.showLoading({ 
        title: '正在提交...',
        mask: true 
      });
      
      try {
        // 4. 准备提交数据
        const submissionData = this.prepareSubmissionData();
        
        
        // 5. 调用后端API
        this.submitToServer(submissionData);
        
      } catch (error) {
        uni.hideLoading();
        uni.showToast({ 
          title: '数据准备失败，请重试', 
          icon: 'none' 
        });
        this.isProcessing = false;
      }
    },
    
    // 准备提交到后端的数据
    prepareSubmissionData() {
      // 使用缓存管理器的统一方法
      const submissionData = prepareSubmissionData();
      
      if (!submissionData) {
        console.error('❌ 无法准备提交数据');
        return null;
      }
      
      console.log('✅ 提交数据已准备:', {
        orderNo: submissionData.orderInfo.orderNo,
        successCount: submissionData.successRecords.length,
        failureCount: submissionData.failureRecords.length
      });
      
      return submissionData;
    },
    
    // 提交到服务器
    async submitToServer(submissionData) {
      try {
        // 显示加载状态
        uni.showLoading({ 
          title: '正在提交...',
          mask: true 
        });

        // 调用后端API保存扫描数据
        // 注意：这里假设后端API返回的数据结构与mockResponse类似
        const response = await saveScanRecords(submissionData); 


        // 6. 处理成功响应
        // 假设后端返回的数据结构是 { code: '00000', message: '...', data: {...} }
        if (response && response.statusCode === 200 && response.data && response.data.code === '00000') { 
          // 提交成功，清空本地缓存（使用新缓存系统）
          clearScanCacheData();
          
          // 立即更新界面状态以反映缓存清空
          this.forceUIUpdate();
          
          uni.hideLoading();
          uni.showToast({ 
            title: response.data.message || '任务完成，数据已提交', 
            icon: 'success',
            duration: 2000
          });
          
          // 成功后延迟返回程序选择页面，给用户足够时间看到成功信息
          setTimeout(() => {
            // 显示返回提示
            uni.showToast({
              title: '即将返回程序选择页面',
              icon: 'none',
              duration: 1000
            });
            
            setTimeout(() => {
              // 清空所有缓存
              this.clearAllCache();

              // 返回程序选择页面（页面跳转时自动清理组件状态）
              uni.redirectTo({
                url: '/pages/select/select'
              });
            }, 1000);
          }, 2000); // 2秒延迟，与第一个Toast显示时间一致
          
        } else {
          // 业务逻辑失败
          // 从响应中提取错误信息，如果没有则使用默认信息
          const errorMessage = (response && response.data && response.data.message) || '提交失败';
          throw new Error(errorMessage);
        }
        
      } catch (error) {
        
        uni.hideLoading();
        // 显示用户友好的错误信息，优先使用uniRequest设置的userMessage
        const userMessage = error.userMessage || error.message || '记录操作失败，请重试';
        uni.showToast({ 
          title: userMessage, 
          icon: 'none' 
        });
        
        // 在失败情况下，保留缓存数据以便重试
        // 但记录失败次数，防止缓存无限堆积
        this.incrementSubmitFailCount();
        
        // 失败时重置状态
        this.isProcessing = false;
      }
      // 注意：成功情况下不在这里重置状态，由延迟跳转逻辑管理
    },
    
    // 延迟函数（用于模拟网络请求）
    delay(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    },
    
    // 清空扫描记录（使用新缓存系统）
    clearScanRecords() {
      try {
        clearScanCacheData();
        
        // 重置响应式数据
        this.currentUniquePartCount = 0;
        this.forceUIUpdate();
        
        return true;
      } catch (error) {
        return false;
      }
    },
    
    // 认证失败计数（防止缓存堆积）
    incrementAuthFailCount() {
      this.authFailCount++;
      if (this.authFailCount >= this.AUTH_FAIL_LIMIT) {
        console.warn(`认证失败超过${this.AUTH_FAIL_LIMIT}次，清理缓存`);
        this.clearAllCache();
        this.authFailCount = 0;
      }
    },
    
    // 提交失败计数（防止缓存堆积）
    incrementSubmitFailCount() {
      this.submitFailCount++;
      if (this.submitFailCount >= this.SUBMIT_FAIL_LIMIT) {
        console.warn(`提交失败超过${this.SUBMIT_FAIL_LIMIT}次，清理缓存`);
        this.clearAllCache();
        this.submitFailCount = 0;
      }
    },
    
    // 设置部品批次ID输入框焦点（模仿程序选择页面的成功实现）
    focusPartBatchIdInput() {
      // 先清除焦点，再设置焦点以确保触发focus属性的变化
      this.isPartBatchIdFocused = false;
      this.$nextTick(() => {
        this.isPartBatchIdFocused = true;
      });
    },
    
    // 系统预热机制：模拟"取消+手动回车"操作解决首次扫描问题
    performSystemWarmup() {
      // 轻量级预热处理：只做焦点管理，不触发业务逻辑
      // 模拟焦点切换激活事件系统
      this.isPartBatchIdFocused = false;
      
      setTimeout(() => {
        // 重新设置焦点，激活输入事件系统
        this.isPartBatchIdFocused = true;
      }, 150);
    },
    
    // 清理所有缓存（使用双缓存系统）
    clearAllCache() {
      try {
        // 使用双缓存系统清理
        const result = clearAllCacheData();
        console.log('✅ 所有缓存已清理:', result);
      } catch (error) {
        console.error('❌ 清理缓存失败:', error);
      }
    },
    
    // 重置页面状态
    resetPageState() {
      this.status = '';
      this.partNumber = '';
      this.zAxisId = '';
      this.inputPartBatchId = '';
      this.lastFailureReason = '';
      
      // 重置响应式计数器
      this.currentUniquePartCount = 0;
      
      // 强制更新界面以确保按钮状态正确
      this.forceUIUpdate();
      
      // 重置后将焦点设置到部品批次ID输入框
      this.$nextTick(() => {
        this.isPartBatchIdFocused = false;
        setTimeout(() => {
          this.isPartBatchIdFocused = true;
        }, 100);
      });
    },
  },
};
</script>

<style lang="scss">
.container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--window-top));
  background-color: #f2f2f2; /* 浅灰色背景 */
  font-size: 18px; /* 字体大小适中 */
}

.content-area {
  flex: 1;
  padding: 5px;
  overflow-y: auto;
  background-color: #f2f2f2;
  min-height: 0;
}

.status-indicator {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 0;
  border-bottom: 1px solid #ccc;
  margin-bottom: 5px;
  width: 100%;
  min-height: 25px; /* Reserve space */
}

.progress-text {
  color: black;
  margin-left: 5px;
  font-size: 24px;
  font-weight: bold;
}

.progress-info {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.status-value {
  font-size: 24px;
  font-weight: bold;
  margin-right: auto;
}

.info-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.info-item-row {
  display: flex;
  flex-direction: row;
  gap: 10px;
}

.half-width {
  flex: 1;
}

.input-field {
  flex: 1;
  font-size: 16px;
  color: #000;
  background-color: white;
  border: 2px solid #999;
  padding: 6px;
  min-height: 32px;
  box-sizing: border-box;
}

/* 新增：部品批次ID 输入框的样式，字体稍小 */
.small-input {
  font-size: 14px; /* 调整为你认为合适的大小 */
}

.info-item-inline {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
  position: relative; /* For absolute positioning of hidden input */
}

.label-inline {
  font-size: 18px;
  color: #333;
  font-weight: bold;
  margin-right: 10px;
  min-width: 100px;
}

/* 新增：部品批次ID 标签的样式，字体稍小 */
.small-label {
  font-size: 16px; /* 调整为你认为合适的大小 */
  color: #333;
  font-weight: bold;
  margin-right: 10px;
  min-width: 100px;
}

.value-inline {
  flex: 1;
  font-size: 18px;
  color: #000;
  background-color: transparent;
  border: none;
  padding: 12px;
  min-height: 40px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}


/* 输入框容器样式 */
.input-container {
  position: relative;
  flex: 1;
}

/* 带清空按钮的输入框样式 */
.input-with-clear-btn {
  padding-right: 30px; /* 为清空按钮留出空间 */
}

.clear-btn {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 18px;
  color: #999;
  cursor: pointer;
  z-index: 999; /* 提高层级确保可点击 */
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.95);
  border: 1px solid #ddd;
  font-weight: bold;
}

.clear-icon {
  font-size: 18px;
  color: #999;
  font-weight: bold;
}

.clear-btn:active {
  color: #666;
  background-color: rgba(255, 255, 255, 1);
}

.clear-btn:active .clear-icon {
  color: #666;
}

.button-group {
    display: flex;
    justify-content: space-between;
    padding: 5px;
    background-color: #f2f2f2;
    height: 60px;
    align-items: center;
}

.btn {
    width: 80px;
    height: 35px;
    border-radius: 6px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 14px;
    font-weight: bold;
    cursor: pointer;
    border: none;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    transition: all 0.2s;
}

.btn:active {
    transform: translateY(2px);
    box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}

.btn-back {
    background-color: #607D8B; /* 蓝灰色 - 低调的辅助功能 */
    color: white;
    border: 1px solid #546E7A;
}

.btn-back:hover {
    background-color: #546E7A;
    transform: translateY(1px);
}

.btn-back:active {
    background-color: #455A64;
    transform: translateY(2px);
}

.btn-back:disabled,
.btn-back.btn-disabled {
    background-color: #cccccc !important; /* Gray for disabled */
    color: #666666 !important;
    opacity: 0.6 !important;
    cursor: not-allowed !important;
    pointer-events: none !important; /* Completely prevent clicks */
    border: none !important; /* Remove border in disabled state */
}

.btn-back:disabled:active,
.btn-back.btn-disabled:active {
    transform: none !important; /* Prevent active animation */
    box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
}

.btn-continue {
    background-color: #007bff; /* Blue for continue */
    color: white;
}

.btn-continue:disabled,
.btn-continue.btn-disabled {
  background-color: #cccccc !important; /* Gray for disabled */
  color: #666666 !important;
  opacity: 0.6 !important;
  cursor: not-allowed !important;
  pointer-events: none !important; /* Completely prevent clicks */
}

.btn-continue:disabled:active,
.btn-continue.btn-disabled:active {
  transform: none !important; /* Prevent active animation */
  box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
}

.btn-complete {
    background-color: #4CAF50; /* Green for complete */
    color: white;
}

.btn-complete:disabled,
.btn-complete.btn-disabled {
  background-color: #cccccc !important; /* Gray for disabled */
  color: #666666 !important;
  opacity: 0.6 !important;
  cursor: not-allowed !important;
  pointer-events: none !important; /* Completely prevent clicks */
}

.btn-complete:disabled:active,
.btn-complete.btn-disabled:active {
  transform: none !important; /* Prevent active animation */
  box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
}

/* 自定义认证模态框样式 */
.auth-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6); /* 半透明背景 */
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 999; /* 调整 z-index，确保 toast 可以显示在其上方 */
}

.auth-modal-content {
  width: 80%;
  background-color: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.auth-modal-header {
  padding: 10px 5px 5px 5px; /* 进一步减小内边距，特别是底部 */
  text-align: center;
  /* 移除 border-bottom */
}

.auth-modal-title {
  font-size: 16px;
  font-weight: bold;
}

.auth-modal-body {
  padding: 5px 10px 10px 10px; /* 减小内边距，特别是顶部 */
}

/* 警告信息样式 */
.auth-warning {
  margin-bottom: 12px;
  padding: 10px 8px;
  background-color: #ffebee; /* 浅红色背景 */
  border-radius: 4px;
  text-align: center;
  width: 100%;
  box-sizing: border-box;
}

.auth-warning-text {
  color: #d32f2f; /* 红色文字 */
  font-size: 13px;
  font-weight: bold;
  line-height: 1.5;
  word-wrap: break-word;
  word-break: break-all;
  display: block;
  margin: 0;
  padding: 0;
}

.auth-input {
  width: 100%;
  margin-bottom: 8px; /* 减小底部边距 */
  padding: 6px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  min-height: 28px;
  font-size: 14px;
}

/* 清除按钮样式美化 */
.clear-btn {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  background: linear-gradient(135deg, #ff6b6b, #ee5a52);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  transition: all 0.2s ease;
  z-index: 10;
}

.clear-btn:hover {
  background: linear-gradient(135deg, #ff5252, #e53e3e);
  transform: translateY(-50%) scale(1.1);
}

.clear-btn:active {
  transform: translateY(-50%) scale(0.95);
}

.clear-icon {
  color: white;
  font-size: 16px;
  font-weight: bold;
  line-height: 1;
}

/* 认证模态框清除按钮 */
.auth-input-container {
  position: relative;
  width: 100%;
}

.auth-clear-btn {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  background: linear-gradient(135deg, #999, #777);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  z-index: 10;
}

.auth-clear-btn:hover {
  background: linear-gradient(135deg, #666, #444);
  transform: translateY(-50%) scale(1.1);
}

.auth-clear-btn .clear-icon {
  color: white;
  font-size: 12px;
  font-weight: bold;
  line-height: 1;
}

.auth-modal-footer {
  display: flex;
  justify-content: space-around;
  padding: 5px 10px 10px 10px; /* 减小内边距，特别是顶部 */
  /* 移除 border-top */
}

.auth-button {
  padding: 2px 12px; /* 再次减小上下内边距 */
  border: none;
  border-radius: 4px;
  cursor: pointer;
  height: 32px; /* 固定高度，更精确控制 */
  font-size: 14px;
  min-width: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.auth-button-cancel {
  background-color: #f0f0f0;
  color: #333;
}

.auth-button-confirm {
  background-color: #007aff; /* 蓝色，符合 UniApp 默认按钮色 */
  color: white;
}
</style>